home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / memory.c < prev    next >
C/C++ Source or Header  |  1996-06-12  |  10KB  |  420 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * Memory management
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "memory.h"
  15. #include "custom.h"
  16. #include "cia.h"
  17. #include "ersatz.h"
  18.  
  19. int ersatzkickfile = 0;
  20.  
  21. int buserr;
  22. addrbank membanks[65536];
  23.  
  24. /* Default memory access functions */
  25.  
  26. int default_check(CPTR a, ULONG b)
  27. {
  28.     return 0;
  29. }
  30.  
  31. UWORD *default_xlate(CPTR a)
  32. {
  33.     fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
  34.     return 0;
  35. }
  36.  
  37. /* A dummy bank that only contains zeros */
  38.  
  39. static ULONG dummy_lget(CPTR) REGPARAM;
  40. static UWORD dummy_wget(CPTR) REGPARAM;
  41. static UBYTE dummy_bget(CPTR) REGPARAM;
  42. static void  dummy_lput(CPTR, ULONG) REGPARAM;
  43. static void  dummy_wput(CPTR, UWORD) REGPARAM;
  44. static void  dummy_bput(CPTR, UBYTE) REGPARAM;
  45. static int   dummy_check(CPTR addr, ULONG size) REGPARAM;
  46. static UWORD *dummy_xlate(CPTR addr) REGPARAM;
  47.  
  48. ULONG dummy_lget(CPTR addr)
  49. {
  50.     return 0;
  51. }
  52.  
  53. UWORD dummy_wget(CPTR addr)
  54. {
  55.     return 0;
  56. }
  57.  
  58. UBYTE dummy_bget(CPTR addr)
  59. {
  60.     return 0;
  61. }
  62.  
  63. void dummy_lput(CPTR addr, ULONG l)
  64. {
  65. }
  66.  
  67. void dummy_wput(CPTR addr, UWORD w)
  68. {
  69. }
  70.  
  71. void dummy_bput(CPTR addr, UBYTE b)
  72. {
  73. }
  74.  
  75. int dummy_check(CPTR addr, ULONG size)
  76. {
  77.     return 0;
  78. }
  79.  
  80. UWORD *dummy_xlate(CPTR addr)
  81. {
  82.     return NULL;
  83. }
  84.  
  85. /* Chip memory */
  86.  
  87. UWORD chipmemory[chipmem_size/2];
  88.  
  89. static ULONG chipmem_lget(CPTR) REGPARAM;
  90. static UWORD chipmem_wget(CPTR) REGPARAM;
  91. static UBYTE chipmem_bget(CPTR) REGPARAM;
  92. static void  chipmem_lput(CPTR, ULONG) REGPARAM;
  93. static void  chipmem_wput(CPTR, UWORD) REGPARAM;
  94. static void  chipmem_bput(CPTR, UBYTE) REGPARAM;
  95. static int   chipmem_check(CPTR addr, ULONG size) REGPARAM;
  96. static UWORD *chipmem_xlate(CPTR addr) REGPARAM;
  97.  
  98. ULONG chipmem_lget(CPTR addr)
  99. {
  100.     addr -= chipmem_start & (chipmem_size-1);
  101.     addr &= chipmem_size-1;
  102.     return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1];
  103. }
  104.  
  105. UWORD chipmem_wget(CPTR addr)
  106. {
  107.     addr -= chipmem_start & (chipmem_size-1);
  108.     addr &= chipmem_size-1;
  109.     return chipmemory[addr >> 1];
  110. }
  111.  
  112. UBYTE chipmem_bget(CPTR addr)
  113. {
  114.     addr -= chipmem_start & (chipmem_size-1);
  115.     addr &= chipmem_size-1;
  116.     if (addr & 1) 
  117.     return chipmemory[addr >> 1];
  118.     else
  119.     return chipmemory[addr >> 1] >> 8;
  120. }
  121.  
  122. void chipmem_lput(CPTR addr, ULONG l)
  123. {
  124.     addr -= chipmem_start & (chipmem_size-1);
  125.     addr &= chipmem_size-1;
  126.     chipmemory[addr >> 1] = l >> 16;
  127.     chipmemory[(addr >> 1)+1] = (UWORD)l;
  128. }
  129.  
  130. void chipmem_wput(CPTR addr, UWORD w)
  131. {
  132.     addr -= chipmem_start & (chipmem_size-1);
  133.     addr &= chipmem_size-1;
  134.     chipmemory[addr >> 1] = w;
  135. }
  136.  
  137. void chipmem_bput(CPTR addr, UBYTE b)
  138. {
  139.     addr -= chipmem_start & (chipmem_size-1);
  140.     addr &= chipmem_size-1;
  141.     if (!(addr & 1)) {
  142.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  143.     } else {
  144.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b;
  145.     }
  146. }
  147.  
  148. int chipmem_check(CPTR addr, ULONG size)
  149. {
  150.     addr -= chipmem_start & (chipmem_size-1);
  151.     addr &= chipmem_size-1;
  152.     return (addr + size) < chipmem_size;
  153. }
  154.  
  155. UWORD *chipmem_xlate(CPTR addr)
  156. {
  157.     addr -= chipmem_start & (chipmem_size-1);
  158.     addr &= chipmem_size-1;
  159.     return chipmemory + (addr >> 1);
  160. }
  161.  
  162. /* Slow memory */
  163.  
  164. static UWORD *bogomemory;
  165.  
  166. static ULONG bogomem_lget(CPTR) REGPARAM;
  167. static UWORD bogomem_wget(CPTR) REGPARAM;
  168. static UBYTE bogomem_bget(CPTR) REGPARAM;
  169. static void  bogomem_lput(CPTR, ULONG) REGPARAM;
  170. static void  bogomem_wput(CPTR, UWORD) REGPARAM;
  171. static void  bogomem_bput(CPTR, UBYTE) REGPARAM;
  172. static int  bogomem_check(CPTR addr, ULONG size) REGPARAM;
  173. static UWORD *bogomem_xlate(CPTR addr) REGPARAM;
  174.  
  175. ULONG bogomem_lget(CPTR addr)
  176. {
  177.     addr -= bogomem_start & (bogomem_size-1);
  178.     addr &= bogomem_size-1;
  179.     return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1];
  180. }
  181.  
  182. UWORD bogomem_wget(CPTR addr)
  183. {
  184.     addr -= bogomem_start & (bogomem_size-1);
  185.     addr &= bogomem_size-1;
  186.     return bogomemory[addr >> 1];
  187. }
  188.  
  189. UBYTE bogomem_bget(CPTR addr)
  190. {
  191.     addr -= bogomem_start & (bogomem_size-1);
  192.     addr &= bogomem_size-1;
  193.     if (addr & 1)
  194.     return bogomemory[addr >> 1];
  195.     else
  196.     return bogomemory[addr >> 1] >> 8;
  197. }
  198.  
  199. void bogomem_lput(CPTR addr, ULONG l)
  200. {
  201.     addr -= bogomem_start & (bogomem_size-1);
  202.     addr &= bogomem_size-1;
  203.     bogomemory[addr >> 1] = l >> 16;
  204.     bogomemory[(addr >> 1)+1] = (UWORD)l;
  205. }
  206.  
  207. void bogomem_wput(CPTR addr, UWORD w)
  208. {
  209.     addr -= bogomem_start & (bogomem_size-1);
  210.     addr &= bogomem_size-1;
  211.     bogomemory[addr >> 1] = w;
  212. }
  213.  
  214. void bogomem_bput(CPTR addr, UBYTE b)
  215. {
  216.     addr -= bogomem_start & (bogomem_size-1);
  217.     addr &= bogomem_size-1;
  218.     if (!(addr & 1)) {
  219.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  220.     } else {
  221.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b;
  222.     }
  223. }
  224.  
  225. int bogomem_check(CPTR addr, ULONG size)
  226. {
  227.     addr -= bogomem_start & (bogomem_size-1);
  228.     addr &= bogomem_size-1;
  229.     return (addr + size) < bogomem_size;
  230. }
  231.  
  232. UWORD *bogomem_xlate(CPTR addr)
  233. {
  234.     addr -= bogomem_start & (bogomem_size-1);
  235.     addr &= bogomem_size-1;
  236.     return bogomemory + (addr >> 1);
  237. }
  238.  
  239. /* Kick memory */
  240.  
  241. static int zkickfile = 0;
  242. static UWORD kickmemory[kickmem_size/2];
  243.  
  244. static ULONG kickmem_lget(CPTR) REGPARAM;
  245. static UWORD kickmem_wget(CPTR) REGPARAM;
  246. static UBYTE kickmem_bget(CPTR) REGPARAM;
  247. static void  kickmem_lput(CPTR, ULONG) REGPARAM;
  248. static void  kickmem_wput(CPTR, UWORD) REGPARAM;
  249. static void  kickmem_bput(CPTR, UBYTE) REGPARAM;
  250. static int  kickmem_check(CPTR addr, ULONG size) REGPARAM;
  251. static UWORD *kickmem_xlate(CPTR addr) REGPARAM;
  252.  
  253. ULONG kickmem_lget(CPTR addr)
  254. {
  255.     addr -= kickmem_start & (kickmem_size-1);
  256.     addr &= kickmem_size-1;
  257.     return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1];
  258. }
  259.  
  260. UWORD kickmem_wget(CPTR addr)
  261. {
  262.     addr -= kickmem_start & (kickmem_size-1);
  263.     addr &= kickmem_size-1;
  264.     return kickmemory[addr >> 1];
  265. }
  266.  
  267. UBYTE kickmem_bget(CPTR addr)
  268. {
  269.     addr -= kickmem_start & (kickmem_size-1);
  270.     addr &= kickmem_size-1;
  271.     return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  272. }
  273.  
  274. void kickmem_lput(CPTR a, ULONG b)
  275. {
  276. }
  277.  
  278. void kickmem_wput(CPTR a, UWORD b)
  279. {
  280. }
  281.  
  282. void kickmem_bput(CPTR a, UBYTE b)
  283. {
  284. }
  285.  
  286. int kickmem_check(CPTR addr, ULONG size)
  287. {
  288.     addr -= kickmem_start & (kickmem_size-1);
  289.     addr &= kickmem_size-1;
  290.     return (addr + size) < kickmem_size;
  291. }
  292.  
  293. UWORD *kickmem_xlate(CPTR addr)
  294. {
  295.     addr -= kickmem_start & (kickmem_size-1);
  296.     addr &= kickmem_size-1;
  297.     return kickmemory + (addr >> 1);
  298. }
  299.  
  300. static int load_kickstart(void)
  301. {
  302.     int i;
  303.     ULONG cksum = 0, prevck = 0;
  304.     unsigned char buffer[8];
  305.     
  306.     FILE *f = fopen(romfile, "rb");
  307.     
  308.     if (f == NULL) {    
  309.         fprintf(stderr, "No Kickstart ROM found.\n");
  310.     return 0;
  311.     }
  312.     
  313.     fread(buffer, 1, 8, f);
  314.     if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) {
  315.     fprintf(stderr, "You seem to have a ZKick file there... You probably lose.\n");
  316.     zkickfile = 1;
  317.     } else 
  318.     fseek(f, 0, SEEK_SET);
  319.     
  320.     i = fread(kickmemory, 1, kickmem_size, f);
  321.     if (i == kickmem_size/2) {
  322.     fprintf(stderr, "Warning: Kickstart is only 256K.\n");
  323.     memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/2);
  324.     } else if (i != kickmem_size) {
  325.     fprintf(stderr, "Error while reading Kickstart.\n");
  326.     return 0;
  327.     }
  328.     fclose (f);
  329.     
  330.     for (i = 0; i < kickmem_size/2; i++) {
  331.     UWORD *p = kickmemory + i;
  332.     UBYTE *bp = (UBYTE *)p;
  333.     *p = (*bp << 8) | *(bp+1);
  334.     }
  335.  
  336.     for (i = 0; i < kickmem_size/4; i++) {
  337.     ULONG data = kickmemory[i*2]*65536 + kickmemory[i*2+1];
  338.     cksum += data;
  339.     if (cksum < prevck)
  340.         cksum++;
  341.     prevck = cksum;
  342.     }
  343.     if (cksum != 0xFFFFFFFF) {
  344.     fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
  345.     }
  346.     return 1;
  347. }
  348.  
  349. /* Address banks */
  350.  
  351. addrbank dummy_bank = {
  352.     dummy_lget, dummy_wget, dummy_bget,
  353.     dummy_lput, dummy_wput, dummy_bput,
  354.     dummy_xlate, dummy_check
  355. };
  356.  
  357. addrbank chipmem_bank = {
  358.     chipmem_lget, chipmem_wget, chipmem_bget,
  359.     chipmem_lput, chipmem_wput, chipmem_bput,
  360.     chipmem_xlate, chipmem_check
  361. };
  362.  
  363. addrbank bogomem_bank = {
  364.     bogomem_lget, bogomem_wget, bogomem_bget,
  365.     bogomem_lput, bogomem_wput, bogomem_bput,
  366.     bogomem_xlate, bogomem_check
  367. };
  368.  
  369. addrbank kickmem_bank = {
  370.     kickmem_lget, kickmem_wget, kickmem_bget,
  371.     kickmem_lput, kickmem_wput, kickmem_bput,
  372.     kickmem_xlate, kickmem_check
  373. };
  374.  
  375. void memory_init(void)
  376. {
  377.     int i;
  378.     buserr = 0;
  379.  
  380.     memset(chipmemory, 0, sizeof chipmemory);
  381.     
  382.     for(i = 0; i < 65536; i++)
  383.     membanks[i] = dummy_bank;
  384.     
  385.     /* Map the chipmem into all of the lower 16MB */
  386.     map_banks(chipmem_bank, 0x00, 256);
  387.     map_banks(custom_bank, 0xC0, 0x20);
  388.     map_banks(cia_bank, 0xA0, 32);
  389.     map_banks(clock_bank, 0xDC, 1);
  390.     
  391.     if (use_slow_mem && bogomem_size > 0) {
  392.     bogomemory = (UWORD *)malloc (bogomem_size);
  393.         map_banks(bogomem_bank, 0xC0, bogomem_size >> 16);
  394.     }
  395.  
  396.     map_banks(rtarea_bank, 0xF0, 1); 
  397.     rtarea_init ();
  398.     if (!load_kickstart()) {
  399.     init_ersatz_rom(kickmemory);
  400.     ersatzkickfile = 1;
  401.     }
  402.     if (zkickfile)
  403.     map_banks(kickmem_bank, 0x20, 8);
  404.     
  405.     map_banks(kickmem_bank, 0xF8, 8);
  406.     if (!zkickfile)
  407.     map_banks(expamem_bank, 0xE8, 1);
  408. }
  409.  
  410. void map_banks(addrbank bank, int start, int size)
  411. {
  412.     int bnr;
  413.     int hioffs = 0;
  414. #if CPU_LEVEL < 2
  415.     for (hioffs = 0; hioffs < 256; hioffs++)
  416. #endif
  417.     for (bnr = start; bnr < start+size; bnr++) 
  418.         membanks[bnr + hioffs * 256] = bank;
  419. }
  420.